繼承可讓您建立新的類別,以重複使用、擴充和修改其他類別中定義的行為
成員被繼承的類別稱為「基底類別」(父類別)
而繼承這種成員的類別即稱為「衍生類別」(子類別)
繼承最主要個功用正如上方粗體字
為的是增加"重用性"
C#不支援多重繼承
意即一個子類別只能有一個父類別
一個人只能有一個爸爸
C++則支援多重繼承(某天你會發現隔壁老王也是你爸爸)
繼承有遞移性
例如B繼承A C繼承B 則C也能使用A的東東
但是C#支援多重實作
(本篇不講介面Inferface,會放在後兩天的文章中)
這時候就要拿出繼承範例中最常被提到Animal類別了(還有shape)
我們先來定義動物的行為和屬性吧
Animal.cs
using System;
namespace Inheritance
{
public class Animal
{
protected string Name;
public void Move()
{
Console.WriteLine("Walk");
}
public void GetName()
{
Console.WriteLine($"動物的名字是{Name}");
}
}
}
我們宣告了一個protect的欄位Name
這個欄位只有父類別(Animal)和繼承Animal的子類別能使用
另外宣告了兩個public的方法
Move()跟GetName
那我們現在讓狗狗來繼承動物類別吧
Dog.cs
namespace Inheritance
{
public class Dog : Animal
{
public Dog()
{
Name = "Dog";
}
public void WagTail()
{
Console.WriteLine($"{Name}搖了搖尾巴");
}
}
}
我們使用 ":"來繼承(實作也是)
裡面只有一個建構式是把Name設為Dog
跟一個搖尾巴的方法
讓我們來看看Main
Program.cs
namespace Inheritance
{
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog();
dog.GetName();
}
}
}
//動物的名字是Dog
太神奇了吧傑克
明明狗狗類別裡沒有GetName()
但是卻能使用GetName()
這就是繼承的威力
現在讓我們來看看小鳥
小鳥一樣有Move的功能
也有GetName()的方法
所以我們讓小鳥繼承Animal的類別
修但幾類
我們仔細看看Animal 中的 Move()方法
他是用Walk來形容移動
可是我鳥鳥明明就是用飛的
當然你也可以幫鳥鳥宣告一個fly方法讓他飛
但是鳥鳥這時候就用不到move方法了
讓他繼承animal就有點沒意義了
所以我們來改寫一下Animal的Move方法
public virtual void Move()
{
Console.WriteLine("Walk");
}
我們在void前面加上"virtual"關鍵字
代表這個方法是可以被子類別覆寫(override)的
那來看看鳥鳥吧
Bird.cs
using System;
namespace Inheritance
{
public class Bird:Animal
{
public Bird()
{
Name = "Bird";
}
public override void Move()
{
Console.WriteLine("這樣太危險,我飛太遠");
}
}
}
我們使用"override"關鍵字來重寫鳥鳥的Move方法
來看看Main吧
為了比較我也讓狗狗移動了一下
Program.cs
using System;
namespace Inheritance
{
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog();
Bird bird = new Bird();
Console.Write("Dog Move:");
dog.Move();
Console.Write("Bird Move:");
bird.Move();
}
}
}
輸出
如此如此 一般一般
鳥鳥就飛起來了
顧名思義就是抽象
也就是不具體的
意即指宣告但不進行實作
使用"abstract"關鍵字
繼承抽象類別必須實作所有的抽象方法 否則編譯器會報錯
請看範例
我們將Animal 類別改成抽象類別
並且新增一個抽象方法Eat()
using System;
namespace Inheritance
{
public abstract class Animal
{
protected string Name;
public virtual void Move()
{
Console.WriteLine("Move");
}
public void GetName()
{
Console.WriteLine($"動物的名字是{Name}");
}
public abstract void Eat();
}
}
抽象方法只能宣告在抽象類別裡
因為鳥鳥跟狗狗都繼承自animal
所以他們必須要實作Eat()方法
使用override 進行實作
Dog.cs
using System;
namespace Inheritance
{
public class Dog : Animal
{
public Dog()
{
Name = "Dog";
}
public void WagTail()
{
Console.WriteLine($"{Name}搖了搖尾巴");
}
public override void Eat()
{
Console.WriteLine($"{Name}吃肉");
}
}
}
Bird.cs
using System;
namespace Inheritance
{
public class Bird:Animal
{
public Bird()
{
Name = "Bird";
}
public override void Move()
{
Console.WriteLine("這樣太危險,我飛太遠");
}
public override void Eat()
{
Console.WriteLine($"{Name}吃蟲");
}
}
}
這個部分就是偏向"設計"的概念
因為還沒有講到ISP(介面隔離原則)
事實上我們在設計一個系統的時候
應該要針對抽象而不是實作
這樣能夠降低耦合性
能夠提升系統的靈活度
我知道正常人看完都是一頭霧水
因為我也是
這部分感覺要實際看過一些實作的系統成能夠理解
不過會接觸到這部份的人應該也不用看這篇了XDD